package org.hk;

import jdk.nashorn.internal.runtime.linker.JavaAdapterFactory;

import java.lang.reflect.Field;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;

public class StudyReflect {
    public static void main(String[] args) throws ClassNotFoundException, NoSuchFieldException, IllegalAccessException, InstantiationException, NoSuchMethodException, InvocationTargetException {
        //1.得到一个对象（从网络来的对象）不知道具体的类型，可以通过反射机制获得类Class对象的信息，通过类对象可以得到这个类的完整定义（类有哪些成员变量 成员方法），通过反射修改成员变量的值和调用成员方法
        Student student1 = new Student("20200101","冉豪");
        Student student2 = new Student("20200102","许俊");

        Class clazz = student1.getClass();//得到对象的类型对象（类的具体描述）
        String className = clazz.getName();
        System.out.println(className);
        for(Field fd :clazz.getDeclaredFields()){
            System.out.println(fd.getName());
        }
        Field fd = clazz.getDeclaredField("name");
        String  name1 = (String)fd.get(student1);//得到当前值 只需要给fd对象说明是当前那个对象的值
        String  name2 = (String)fd.get(student2);
        System.out.println(name1+" "+name2);
//        for(Method method :clazz.getDeclaredMethods()){
//            System.out.println(method.getName());
//        }
        //2.如果只知道类的名字，也可以通过反射生成类的对象
        Class clazz2 = Class.forName("org.hk.Student");//从已加载的类中找一个叫org.hk.Student的类
        Student student3 = (Student)clazz2.newInstance();//反射生成对象
        //student3.name = "王二";//常规给对象赋值
        Field fd3 = clazz2.getDeclaredField("name");//得到name的字段对象
        fd3.setAccessible(true);//允许通过反射方式修改值
        fd3.set(student3,"王二");
        System.out.println(student3.name);

        //3.可以使用反射来调用方法
        Method method = clazz2.getDeclaredMethod("play");
        int druingTime = (int)method.invoke(student3);
        System.out.println(druingTime);







        Method method2 = clazz2.getDeclaredMethod("play",String.class);
        Object[] objects = {"变形金刚"};
        String result = (String)method2.invoke(student3,"变形金刚");
        System.out.println(result);


        Class[] classes = {String.class,Integer.class};
        Method method3 = clazz2.getDeclaredMethod("play",classes);
        Object[] objects2 = {"变形金刚",80};
        String result3 = (String)method3.invoke(student3,objects2);
        System.out.println(result3);
    }
}
